package com.ky.pro.java.rpc.core.util.http;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.*;
import io.netty.util.AttributeKey;
import lombok.extern.slf4j.Slf4j;

import java.net.InetSocketAddress;

/**
 * @ClassName NettyHttpClient
 * @Description TODO
 * @Date 2022/1/1 20:24
 * @Author kevin
 **/
@Slf4j
public class NettyHttpClient {

    Bootstrap bootstrap;

    EventLoopGroup eventLoopGroup;

    NettyHttpClientHandler clientHandler = new NettyHttpClientHandler();

    public NettyHttpClient() {

        bootstrap = new Bootstrap();
        eventLoopGroup = new NioEventLoopGroup();

        bootstrap.group(eventLoopGroup)
                //长连接
                .option(ChannelOption.SO_KEEPALIVE, true)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<Channel>() {
                    @Override
                    protected void initChannel(Channel channel) {
                        channel.pipeline().addLast(new HttpClientCodec());
                        channel.pipeline().addLast(new HttpObjectAggregator(1024 * 10 * 1024));
                        channel.pipeline().addLast(new HttpContentDecompressor());

                        channel.pipeline().addLast(clientHandler);
                    }
                });

    }

    public static final AttributeKey<FullHttpRequest> ATTR_KEY_REQUEST = AttributeKey.newInstance("request");
    public static final AttributeKey<HttpResponse> ATTR_KEY_RESPONSE = AttributeKey.newInstance("response");

    public HttpResponse sendRequest(FullHttpRequest request, InetSocketAddress endpointAddress) {

        try {
            ChannelFuture cf = bootstrap.connect(endpointAddress);
            cf.channel().attr(ATTR_KEY_REQUEST).set(request);

            Channel ch = cf.sync().channel();
            ch.closeFuture();

            HttpResponse response = null;
            synchronized (request) {
                while (response == null) {
                    request.wait();
                    response = ch.attr(ATTR_KEY_RESPONSE).get();
                }
            }
            return response;
        } catch (InterruptedException e) {
            log.error("处理中断", e);
            return ResponseUtil.createResponseWithException(e);
        }
    }

    public void shutdown() {
        log.info("关闭netty http client...");
        eventLoopGroup.shutdownGracefully();
    }

}
